//
//  XMPages.swift
//  sinaDemo
//
//  Created by Xueming on 2021/4/15.
//

import Foundation
import UIKit
//import JKSwiftExtension
//也可以不复用。复用cell的话需要频繁移除和创建childView
private let cellId = "pageCollectionCell"
enum selectedLineStatus {
    case sameToSingleLabel
    case halfWithSingleLabel
    case custom
}
// MARK: - 配置工具类
open class XMPageConfig:NSObject {
    
    /// 字体大小
        open var titleFont:CGFloat = 15
        /// 文字选中颜色
        open var titleSelectedColor:UIColor = .orange
        /// 文字未选中颜色
        open var titleNormalColor:UIColor = .lightGray
        /// titleView scroll背景颜色
        open var titleViewBackColor:UIColor = .white
        /// 下划线颜色
        open var currentLineColor:UIColor = .orange
        /// 下划线自定义默认宽度
        open var currentLineWidth:CGFloat = 30
        /// 默认下划线模式
        var lineStatus:selectedLineStatus = .halfWithSingleLabel
        /// 单个label菜单宽度（0为平分titleViewFrame宽度）
        open var singleTitleWidth:CGFloat = 0
        /// 设置titleview的frame
        open var titleViewFrame:CGRect = CGRect(x: 0, y: kNavigationHeight, width: kScreenWidth, height: 40)
        /// 整个pageview的frame
        open var pageViewFrame:CGRect = CGRect(x: 0, y: kNavigationHeight, width: kScreenWidth, height: kScreenHeight )
        // selected-》normal变化色差
        open var chromatismSelect:(r:CGFloat,g:CGFloat,b:CGFloat,a:CGFloat)!
        // normal-》selected变化色差
        open var chromatismNormal:(r:CGFloat,g:CGFloat,b:CGFloat,a:CGFloat)!
    }

// MARK: - 各种事件代理

@objc protocol XMPagesDelegate:NSObjectProtocol {
    
    //点击选择了哪一页
    @objc  func selectedPage(pageTag:Int)
    //滑动选择了哪一页
    @objc  func scrollToPage(pageTag:Int)
    //正在翻页
    @objc  func scrollDidScrolling(startPageTag:Int,endPageTag:Int,progress:CGFloat)
    //点击了加号
    @objc  func addBtnClicked()
}
extension XMPagesDelegate{
    //默认实现
    func selectedPage(pageTag:Int){print("extension selectedPage")}
    //默认实现
    func scrollToPage(pageTag:Int){print("extension scrollToPage")}
    //默认实现
    func scrollDidScrolling(startPageTag:Int,endPageTag:Int,progress:CGFloat){print("start page =\(startPageTag),end page = \(endPageTag),progress = \(progress)")}
}
// MARK: - 菜单实现

/// 自定义滚动菜单
class XMPages: NSObject {
    
    /// 配置实例化
    private var pageConfig:XMPageConfig = XMPageConfig()
    
    lazy private var titleView:UIScrollView = {
        let scrollV = UIScrollView.init()
        scrollV.bounces = false
        if #available(iOS 13.0, *) {
            scrollV.automaticallyAdjustsScrollIndicatorInsets = false
        } else {
            // Fallback on earlier versions
        }
        scrollV.showsHorizontalScrollIndicator = false
        scrollV.showsVerticalScrollIndicator = false
        scrollV.alwaysBounceHorizontal = false
        scrollV.isScrollEnabled = false
        return scrollV
    }()
//    private var addBtn:UIButton = UIButton.init(type: .custom).then { add in
//        add.setBackgroundImage(JKPOP.image(light: UIImage(named: "add_img"), dark: UIImage(named: "add_img")), for: .normal)
//    }
//    private let addBtnSize = CGSize(width: 20.zoom(), height: 20.zoom())
    private var titles:[String] = [String]()
    private var singleLabelArray:[UILabel] = [UILabel]()
    private var viewControllers:[UIViewController] = [UIViewController]()
    private var currentLabel:UILabel!
    private var TapPaging:Bool = false
    private var currentLineLabel:UILabel = UILabel.init()
    private var lastOffset:CGFloat = 0.0
    lazy private var collectionView:UICollectionView = {
        let size = CGSize(width: self.pageConfig.pageViewFrame.size.width, height: self.pageConfig.pageViewFrame.size.height - self.titleView.frame.height)
        let flowLayout:UICollectionViewFlowLayout = UICollectionViewFlowLayout.init()
        flowLayout.itemSize = size
        flowLayout.minimumLineSpacing = 0
        flowLayout.minimumInteritemSpacing = 0
        flowLayout.scrollDirection = .horizontal
        let collectionView = UICollectionView.init(frame: CGRect(x: 0, y: titleView.bottom, width: size.width, height: size.height), collectionViewLayout: flowLayout)
                collectionView.backgroundColor = .white
        collectionView.showsHorizontalScrollIndicator = false
        collectionView.dataSource = self
        collectionView.delegate = self
        collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: cellId)
        collectionView.isPagingEnabled = true
        collectionView.bounces = false
        return collectionView
    }()
    private weak var parentView:UIView!
    private weak var parentHeaderView:UIView!
    open weak var delegate:XMPagesDelegate?
    /// 构造函数
    /// - Parameters:
    ///   - titles: 标签数组
    ///   - viewControllers: 子控制器数组
    ///   - parentCtr: 添加到哪个控制器上
    ///   - pageConfig: 标签工具配置类
    init(titles:[String],viewControllers:[UIViewController],parentHeaderView:UIView,parentView:UIView,pageConfig:XMPageConfig) {
        super.init()
        self.titles = titles;self.viewControllers = viewControllers;self.parentView = parentView;self.pageConfig = pageConfig;self.parentHeaderView = parentHeaderView;
        delegate = parentView as? XMPagesDelegate
        setUpUI()
    }
    /// 构造函数
    /// - Parameters:
    ///   - titles: 标签数组
    ///   - viewControllers: 子控制器数组
    ///   - parentCtr: 添加到哪个控制器上
    ///
    
    
    /// 构造函数
    /// - Parameters:
    ///   - titles: 标签数组
    ///   - viewControllers: 子控制器数组
    ///   - parentView: 添加到哪个view上
    ///   - parentHeaderView: 组头添加到哪个view上
    init(titles:[String],viewControllers:[UIViewController],parentView:UIView,parentHeaderView:UIView) {
        super.init()
        self.titles = titles;self.viewControllers = viewControllers;self.parentView = parentView;self.parentHeaderView = parentHeaderView;
        delegate = parentView as? XMPagesDelegate
        setUpUI()
    }
    public func reSetChildControllers(){
        
    }
    public func canScrollEnabled(canPage:Bool){
        self.collectionView.isScrollEnabled = canPage
    }
    private func setUpUI(){
        if titles.count != viewControllers.count {
            XMLog("[XMPages]warning-->数组不匹配")
            return
        }
        titleView.backgroundColor = pageConfig.titleViewBackColor
        pageConfig.chromatismNormal = self.transColorBeginColorAndEndColor(beginColor: pageConfig.titleNormalColor, endColor: pageConfig.titleSelectedColor)
        pageConfig.chromatismSelect = self.transColorBeginColorAndEndColor(beginColor: pageConfig.titleSelectedColor, endColor: pageConfig.titleNormalColor)
//        for ctr in viewControllers {
//            parentCtr.addChild(ctr)
//        }
        titleView.frame = pageConfig.titleViewFrame
        parentHeaderView.addSubview(titleView)
        parentView.addSubview(collectionView)
        for (index,title) in self.titles.enumerated() {
            let label:UILabel = UILabel.init()
            label.backgroundColor = pageConfig.titleViewBackColor
            label.tag = index
            label.text = title
            label.textColor = pageConfig.titleNormalColor
            label.textAlignment = .center
            label.font = UIFont.systemFont(ofSize: 15)
            if pageConfig.singleTitleWidth == 0 {
                pageConfig.singleTitleWidth = (pageConfig.titleViewFrame.width / titles.count.floatValue)
                //没用设置宽度，默认均分
                label.frame = CGRect(x: pageConfig.singleTitleWidth * index.floatValue, y: 0, width: pageConfig.singleTitleWidth, height: pageConfig.titleViewFrame.height)
            }else{
                //设置宽度就不均分了
                label.frame = CGRect(x: pageConfig.singleTitleWidth * index.floatValue, y: 0, width: pageConfig.singleTitleWidth, height: pageConfig.titleViewFrame.height)
            }
            label.isUserInteractionEnabled = true
            label.addGestureRecognizer(UITapGestureRecognizer.init(target: self, action:#selector(self.labelClick(tap:)) ))
            singleLabelArray.append(label)
            titleView.addSubview(label)
        }
//        addBtn.addTarget(self, action: #selector(self.addBtnClick), for: .touchUpInside)
//        addBtn.frame = CGRect(x: titleView.frame.size.width - addBtnSize.width - 10, y: titleView.frame.size.height / 2 - addBtnSize.height / 2, width: addBtnSize.width, height: addBtnSize.height)
//        titleView.addSubview(addBtn)
        currentLabel = singleLabelArray.first
        currentLabel.textColor = pageConfig.titleSelectedColor
        
        let grayline:UILabel = UILabel.init(frame: CGRect(x: 0, y: 0, width: pageConfig.titleViewFrame.width, height: 1))
        grayline.backgroundColor = .gray
        currentLineLabel.backgroundColor = pageConfig.currentLineColor
        currentLineLabel.frame.size = CGSize(width: (pageConfig.lineStatus == .halfWithSingleLabel ? pageConfig.lineStatus == .custom ? pageConfig.currentLineWidth : currentLabel.frame.size.width/2 : currentLabel.frame.size.width ), height: 5)
        currentLineLabel.center.x = currentLabel.center.x
        currentLineLabel.bottom = pageConfig.titleViewFrame.height
        pageConfig.currentLineWidth = currentLineLabel.frame.width
        grayline.center.y = currentLineLabel.bottom
        titleView.addSubview(grayline)
        titleView.addSubview(currentLineLabel)
        titleView.contentSize = CGSize(width: singleLabelArray.last?.frame.maxX ?? 0, height: pageConfig.titleViewFrame.maxY)
    }
    @objc func addBtnClick(){
        self.delegate?.addBtnClicked()
    }
}
// MARK: - 代理方法们

extension XMPages:UICollectionViewDataSource,UICollectionViewDelegate{
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        titles.count
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath)
        for view in cell.contentView.subviews {
            view.removeFromSuperview()
        }
//        cell.backgroundColor = .blue
        cell.contentView.addSubview(self.viewControllers[indexPath.item].view)
        self.viewControllers[indexPath.item].view.frame = cell.contentView.bounds
        return cell
    }
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        if TapPaging {
            //点击触发到滚动时不响应下面的方法
            return
        }
        //手动滚动时才触发
        let scrollX = scrollView.contentOffset.x
        let proportionUpInt = (ceil(scrollX / pageConfig.pageViewFrame.width))
        let proportionDownInt = (floor(scrollX / pageConfig.pageViewFrame.width))
        let proportion = ( scrollX - proportionDownInt * pageConfig.pageViewFrame.width ) / (pageConfig.pageViewFrame.width / 2)
        var colorProportion = ( scrollX - proportionDownInt * pageConfig.pageViewFrame.width) / (pageConfig.pageViewFrame.width)
        var proportionAll:CGFloat = 0.0
        if proportion > 1{
            proportionAll = 2 - proportion
            currentLineLabel.width = pageConfig.currentLineWidth + currentLabel.frame.width * (proportionAll)
            currentLineLabel.right = proportionUpInt * currentLabel.frame.width  + (currentLabel.frame.width - pageConfig.currentLineWidth)/2 + pageConfig.currentLineWidth
            
        }else {
            proportionAll = proportion
            currentLineLabel.width = pageConfig.currentLineWidth + currentLabel.frame.width * (proportionAll)
            currentLineLabel.left = proportionDownInt * currentLabel.frame.width  + (currentLabel.frame.width - pageConfig.currentLineWidth)/2
            
        }
        //由于 colorProportion 在正好滚动到正页面后又会初始化为0（因为要作为过渡系数，范围是0.0001-0.99999），所以当其为0时就转成1
        // TODO: - 可以继续优化一下（尤其是page-的时候颜色的变化）
        if scrollX - lastOffset > 0 {
            if colorProportion == 0 {
                colorProportion = 1
            }
            //page+
            if Int(proportionUpInt) < self.singleLabelArray.count {
                let rightLabel = self.singleLabelArray[Int(proportionUpInt)]
                if scrollX > currentLabel.tag.floatValue * pageConfig.pageViewFrame.width {
                    print(colorProportion)
                    rightLabel.textColor = self.getCurrentColorWithColor(beginColor: pageConfig.titleNormalColor, coe: colorProportion,marginArray: pageConfig.chromatismNormal)
                    currentLabel.textColor = self.getCurrentColorWithColor(beginColor: pageConfig.titleSelectedColor, coe: ( colorProportion),marginArray: pageConfig.chromatismSelect)
                    self.delegate?.scrollDidScrolling(startPageTag: Int(proportionDownInt), endPageTag: Int(proportionUpInt), progress: proportionAll)
                }else{
//                    print("page-中途返回")
                    if proportionDownInt >= 0{
                        let leftLabel = self.singleLabelArray[Int(proportionDownInt)]
                        leftLabel.textColor = self.getCurrentColorWithColor(beginColor: pageConfig.titleSelectedColor, coe: colorProportion,marginArray: pageConfig.chromatismSelect)
                        currentLabel.textColor = self.getCurrentColorWithColor(beginColor: pageConfig.titleNormalColor, coe: ( colorProportion),marginArray: pageConfig.chromatismNormal)
                    }
                    self.delegate?.scrollDidScrolling(startPageTag: Int(proportionUpInt), endPageTag: Int(proportionDownInt), progress: proportionAll)
                }
                
            }
            
        }else{
            //page-
            if proportionDownInt >= 0 {
                
                let leftLabel = self.singleLabelArray[Int(proportionDownInt)]
                if scrollX >= currentLabel.tag.floatValue * pageConfig.pageViewFrame.width {
                    //中途返回
//                    print("page+中途返回")
                    print(colorProportion)
                    if Int(proportionUpInt) < self.singleLabelArray.count {
                        
                        let rightLabel = self.singleLabelArray[Int(proportionUpInt)]
                        rightLabel.textColor = self.getCurrentColorWithColor(beginColor: pageConfig.titleNormalColor, coe: colorProportion,marginArray: pageConfig.chromatismNormal)
                        currentLabel.textColor = self.getCurrentColorWithColor(beginColor: pageConfig.titleSelectedColor, coe: ( colorProportion),marginArray: pageConfig.chromatismSelect)
                    }
                    self.delegate?.scrollDidScrolling(startPageTag: Int(proportionDownInt), endPageTag: Int(proportionUpInt), progress: proportionAll)
                    
                }else{
                    //正常滑动
//                    print(colorProportion)
                    leftLabel.textColor = self.getCurrentColorWithColor(beginColor: pageConfig.titleNormalColor, coe:1 - colorProportion,marginArray: pageConfig.chromatismNormal)
                    currentLabel.textColor = self.getCurrentColorWithColor(beginColor: pageConfig.titleNormalColor, coe: (colorProportion),marginArray: pageConfig.chromatismNormal)
                    self.delegate?.scrollDidScrolling(startPageTag: Int(proportionUpInt), endPageTag: Int(proportionDownInt), progress: proportionAll)
                }
                
            }
        }
        lastOffset = scrollX
        
    }
    func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {
       //点击titlelabel自动滚动结束后调用
        TapPaging = false
    }
    
    func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
        
        //自动滑动停止
        let scrollX = scrollView.contentOffset.x
        let proportionInt:Int = Int(scrollX / pageConfig.pageViewFrame.width)
        currentLabel = singleLabelArray[proportionInt]
        currentLabel.textColor = pageConfig.titleSelectedColor//防止因为中途返回而导致bug
        if ((delegate?.responds(to: #selector(delegate?.scrollToPage(pageTag:)))) != nil) {
            delegate!.scrollToPage(pageTag: proportionInt)
        }
        //防止滑动过快，导致中间的label文字没有变色的问题
        for tempLabel in singleLabelArray {
            if tempLabel != currentLabel{
                tempLabel.textColor = pageConfig.titleNormalColor
            }
        }
        //        print(currentLabel.tag)
    }
}
// MARK: - 颜色相关

extension XMPages{
    //根据颜色来返回rgb
    private func getRGBDictionaryByColor(originColor:UIColor) -> ((r:CGFloat,g:CGFloat,b:CGFloat,a:CGFloat)){
        var r:CGFloat = 0;var g:CGFloat = 0;var b:CGFloat = 0;var a:CGFloat = 0
        
        r = originColor.r()
        g = originColor.g()
        b = originColor.b()
        a = originColor.a()
        return (r,g,b,a)
    }
    //获取色差
    private func transColorBeginColorAndEndColor(beginColor:UIColor,endColor:UIColor) -> ((r:CGFloat,g:CGFloat,b:CGFloat,a:CGFloat)){
        let beginColorArr = getRGBDictionaryByColor(originColor: beginColor)
        let endColorArr = getRGBDictionaryByColor(originColor: endColor)
       
        return(endColorArr.r - beginColorArr.r,endColorArr.g - beginColorArr.g , endColorArr.b - beginColorArr.b,endColorArr.a - beginColorArr.a)
    }
    //根据色差和过度系数来确定当前颜色
    private func getCurrentColorWithColor(beginColor:UIColor,coe:CGFloat,marginArray:(r:CGFloat,g:CGFloat,b:CGFloat,a:CGFloat))
    -> UIColor
    {
        let beginColorArr = getRGBDictionaryByColor(originColor: beginColor)
        
        let r = beginColorArr.r + coe * marginArray.r
        let g = beginColorArr.g + coe * marginArray.g
        let b = beginColorArr.b + coe * marginArray.b
        let a = beginColorArr.a + coe * marginArray.a
        return UIColor.init(red: r, green: g, blue: b, alpha: a)
    }
}
// MARK: - 点击事件

extension XMPages{
    @objc private func labelClick(tap:UITapGestureRecognizer){
        let label = tap.view as! UILabel
        if label == currentLabel {
            return
        }
        TapPaging = true
        label.textColor = pageConfig.titleSelectedColor
        currentLabel.textColor = pageConfig.titleNormalColor
        currentLabel = label
        UIView.animate(withDuration: 0.3) {
            self.currentLineLabel.center.x = label.center.x
        }
        collectionView.scrollToItem(at: IndexPath(item: label.tag, section: 0), at: .centeredHorizontally, animated: true)
        if ((delegate?.responds(to: #selector(delegate?.selectedPage(pageTag:)))) != nil) {
            delegate!.selectedPage(pageTag: label.tag)
        }
        
    }
}

//UIColor的延展
//将color转换成RGB
extension UIColor {
    func r() -> CGFloat {
        return self.cgColor.components?[0] ?? 0
    }
    
    func g() -> CGFloat {
        let count = self.cgColor.numberOfComponents
        if (count == 2) {
            return self.cgColor.components?[0] ?? 0
        } else {
            return self.cgColor.components?[1] ?? 0
        }
    }
    
    func b() -> CGFloat {
        let count = self.cgColor.numberOfComponents;
        if (count == 2) {
            return self.cgColor.components?[0] ?? 0
        } else {
            return self.cgColor.components?[2] ?? 0
        }
    }
    
    func a() -> CGFloat {
        let count = self.cgColor.numberOfComponents;
        return self.cgColor.components?[count - 1] ?? 0
    }
}
